//
//  EnemyRobot.m
//  LearningCocos
//
//  Created by abyssos on 2014. 3. 6..
//  Copyright (c) 2014년 ainhan. All rights reserved.
//

#import "EnemyRobot.h"

@implementation EnemyRobot

@synthesize delegate;
@synthesize robotWalkingAnim;
@synthesize raisePhaserAnim;
@synthesize shootPhaserAnim;
@synthesize lowerPhaserAnim;
@synthesize torsoHitAnim;
@synthesize headHitAnim;
@synthesize robotDeathAnim;

- (void)dealloc {
    delegate = nil;
    
    [robotDeathAnim release];
    [robotWalkingAnim release];
    [raisePhaserAnim release];
    [shootPhaserAnim release];
    [lowerPhaserAnim release];
    [torsoHitAnim release];
    [headHitAnim release];
    
    [super dealloc];
}

- (void)shootPhaser {
    CCLOG(@"####     SHOOT PHASER --------------------------------------");
    CGPoint phaserFiringPosition;
    PhaserDirection phaserDir;
    CGRect boundingBox = [self boundingBox];
    CGPoint position = [self position];
    
    float xPosition = position.x + boundingBox.size.width * 0.542f;
    float yPosition = position.y + boundingBox.size.height * 0.25f;
    
    if([self flipX]) {
        CCLOG(@"Facing right, Firing to the right");
        phaserDir = kDirectionRight;
    } else {
        CCLOG(@"Facing left, Firing to the left");
        xPosition = xPosition * -1.0f;
        phaserDir = kDirectionLeft;
    }
    
    phaserFiringPosition = ccp(xPosition, yPosition);
    [delegate createPhaserWithDirection:phaserDir andPosition:phaserFiringPosition];
}

- (CGRect)eyesightBoundingBox {
    // Eyesight is 3 robot widths in the direction the robot is facing.
    CGRect robotSightBoundingBox;
    CGRect robotBoundingBox = [self adjustedBoundingBox];
    if([self flipX]) {
        robotSightBoundingBox = CGRectMake(robotBoundingBox.origin.x, robotBoundingBox.origin.y, robotBoundingBox.size.width * 3.0f, robotBoundingBox.size.height);
    } else {
        robotSightBoundingBox = CGRectMake(robotBoundingBox.origin.x - (robotBoundingBox.size.width * 2.0f), robotBoundingBox.origin.y, robotBoundingBox.size.width * 3.0f, robotBoundingBox.size.height);
    }
    
    return robotSightBoundingBox;
}

- (void)changeState:(CharacterStates)newState {
    if(characterState == kStateDead)
        return; // No need to change state further once I am dead
    
    [self stopAllActions];
    id action = nil;
    characterState = newState;
    
    switch (newState) {
        case kStateSpawning:
            [self runAction:[CCFadeOut actionWithDuration:0.0f]];
            // Fadesa out the sprite if it was visible before
            [self setDisplayFrame:[[CCSpriteFrameCache sharedSpriteFrameCache] spriteFrameByName:@"teleport.png"]];
            action = [CCSpawn actions:
                      [CCRotateBy actionWithDuration:1.5f angle:360],
                      [CCFadeIn actionWithDuration:1.5f], nil];
            break;
        
        case kStateIdle:
            CCLOG(@"EnemyRobot -> Changing State to Idle");
            [self setDisplayFrame:[[CCSpriteFrameCache sharedSpriteFrameCache] spriteFrameByName:@"an1_anim1.png"]];
            break;
            
        case kStateWalking:
            CCLOG(@"EnemyRobot -> Changing State to Walking");
            if(isVikingWithinBoundingBox)
                break; // AI will change to Attacking on next frame
            
            float xPositionOffSet = 150.0f;
            if (isVikingWithinSight) {
                if ([vikingCharacter position].x < [self position].x) {
                    xPositionOffSet = xPositionOffSet * -1;
                }
            } else {
                if (CCRANDOM_0_1() > 0.5f) {
                    xPositionOffSet = xPositionOffSet * -1;
                }
                
                if (xPositionOffSet > 0.0f) {
                    [self setFlipX:YES];
                } else {
                    [self setFlipX:NO];
                }
            }
            CCLOG(@"---1-- %@", robotWalkingAnim);
            robotWalkingAnim.restoreOriginalFrame = NO;
            CCLOG(@"---2-- %@", robotWalkingAnim);
            action = [CCSpawn actions:
                      [CCAnimate actionWithAnimation:robotWalkingAnim],
                      [CCMoveTo actionWithDuration:2.4f position:ccp([self position].x + xPositionOffSet, [self position].y)],
                      nil];
            CCLOG(@"---3--");
            break;
            
        case kStateAttacking:
            CCLOG(@"EnemyRobot -> Changing State to Attacking");
            raisePhaserAnim.restoreOriginalFrame = NO;
            shootPhaserAnim.restoreOriginalFrame = NO;
            lowerPhaserAnim.restoreOriginalFrame = NO;
            action = [CCSequence actions:
                      [CCAnimate actionWithAnimation:raisePhaserAnim],
                      [CCDelayTime actionWithDuration:1.0f],
                      [CCAnimate actionWithAnimation:shootPhaserAnim],
                      [CCCallFunc actionWithTarget:self selector:@selector(shootPhaser)],
                      [CCAnimate actionWithAnimation:lowerPhaserAnim],
                      [CCDelayTime actionWithDuration:2.0f],
                      nil];
            break;
            
        case kStateTakingDamage:
            CCLOG(@"EnemyRobot -> Changing State to TakingDamage");
            if ([vikingCharacter getWeaponDamage] > kVikingFistDamage) {
                // If the viking has the mallet, then
                headHitAnim.restoreOriginalFrame = YES;
                action = [CCAnimate actionWithAnimation:headHitAnim];
            } else {
                // Viking does not have weapon, body blow
                torsoHitAnim.restoreOriginalFrame = YES;
                action = [CCAnimate actionWithAnimation:torsoHitAnim];
            }
            break;
            
        case kStateDead:
            CCLOG(@"EnemyRobot -> Going to Dead State");
            robotDeathAnim.restoreOriginalFrame = NO;
            action = [CCSequence actions:[CCAnimate actionWithAnimation:robotDeathAnim], [CCDelayTime actionWithDuration:2.0f], [CCFadeOut actionWithDuration:2.0f], nil];
            break;
            
        default:
            CCLOG(@"Enemy Robot -> Unknown CharState %d", characterState);
            break;
    }
    
    if (action != nil) {
        [self runAction:action];
    }
    
}


- (void)updateStateWithDeltaTime:(ccTime)deltaTime andListOfGameObjects:(CCArray *)listOfGameObjects {
    
    [self checkAndClampSpritePosition];
    
    if((characterState != kStateDead) && (characterHealth <= 0)) {
        [self changeState:kStateDead];
        return;
    }
    
    vikingCharacter = (GameCharacter *)[[self parent] getChildByTag:kVikingSpriteTagValue];
    CGRect vikingBoundingBox = [vikingCharacter adjustedBoundingBox];
    CGRect robotBoundingBox = [self adjustedBoundingBox];
    CGRect robotSightBoundingBox = [self eyesightBoundingBox];
    
    isVikingWithinBoundingBox = CGRectIntersectsRect(vikingBoundingBox, robotBoundingBox) ? YES : NO;
    isVikingWithinSight = CGRectIntersectsRect(vikingBoundingBox, robotSightBoundingBox) ? YES : NO;
    
    if((isVikingWithinBoundingBox) && ([vikingCharacter characterState] == kStateAttacking)) {
        // Viking is attacking this robot
        if((characterState != kStateTakingDamage) && (characterState != kStateDead)) {
            [self setCharacterHealth:[self characterHealth] - [vikingCharacter getWeaponDamage]];
            if(characterHealth > 0) {
                [self changeState:kStateTakingDamage];
            } else {
                [self changeState:kStateDead];
            }
            return; // Nothing to update Further, stop and show damage
        }
    }
    
    if([self numberOfRunningActions] == 0) {
        
        if(characterState == kStateDead) {
            // Robot is dead, remove
            [self setVisible:NO];
            [self removeFromParentAndCleanup:YES];
        } else if ([vikingCharacter characterState] == kStateDead) {
            // Vikig is dead, walk around the scene
            [self changeState:kStateWalking];
        } else if (isVikingWithinSight) {
            [self changeState:kStateAttacking];
        } else {
            // Viking alive and out of sight, resume, walking
            [self changeState:kStateWalking];
        }
    }
}

- (CGRect)adjustedBoundingBox {
    // Shrink the bounding box by 18% on the X axis, and move it to the
    // right by 18% and crop it by 5% on the Y Axis.
    // On the iPad this is 30pixels on the X axis and
    // 10 pixels from the top (Y Axis)
    CGRect enemyRobotBoundingBox = [self boundingBox];
    float xOffsetAmount = enemyRobotBoundingBox.size.width * 0.18f;
    float yCropAmount = enemyRobotBoundingBox.size.height * 0.05f;
    enemyRobotBoundingBox = CGRectMake(enemyRobotBoundingBox.origin.x + xOffsetAmount,
                                       enemyRobotBoundingBox.origin.y,
                                       enemyRobotBoundingBox.size.width - xOffsetAmount,
                                       enemyRobotBoundingBox.size.height - yCropAmount);
    return enemyRobotBoundingBox;
}

#pragma mark -
#pragma mark initAnimations
- (void)initAnimations {
    
    CCLOG(@"# [EnemyRobot] initAnimations..................");
    
    [self setRobotWalkingAnim:[self loadPlistForAnimationWithName:@"robotWalkingAnim" andClassName:NSStringFromClass([self class])]];
    
    [self setRaisePhaserAnim:[self loadPlistForAnimationWithName:@"raisePhaserAnim" andClassName:NSStringFromClass([self class])]];
    
    [self setShootPhaserAnim:[self loadPlistForAnimationWithName:@"shootPhaserAnim" andClassName:NSStringFromClass([self class])]];
    
    [self setLowerPhaserAnim:[self loadPlistForAnimationWithName:@"lowerPhaserAnim" andClassName:NSStringFromClass([self class])]];
    
    [self setTorsoHitAnim:[self loadPlistForAnimationWithName:@"torsoHitAnim" andClassName:NSStringFromClass([self class])]];
    
    [self setHeadHitAnim:[self loadPlistForAnimationWithName:@"headHitAnim" andClassName:NSStringFromClass([self class])]];
    
    [self setRobotDeathAnim:[self loadPlistForAnimationWithName:@"robotDeathAnim" andClassName:NSStringFromClass([self class])]];
}

- (id)initWithSpriteFrameName:(NSString *)spriteFrameName {
    CCLOG(@"# [EnemyRobot] init..................");

    if((self = [super initWithSpriteFrameName:spriteFrameName])) {
        [self initAnimations];
        isVikingWithinBoundingBox = NO;
        isVikingWithinSight = NO;
        gameObjectType = kEnemyTypeAlienRobot;
        srandom(time(NULL));
    }
    
    return self;
}

@end
















